package org.aplikator.appUtils;

import org.aplikator.client.shared.data.ContainerNode;
import org.aplikator.client.shared.data.ListItem;
import org.aplikator.client.shared.data.Operation;
import org.aplikator.client.shared.data.PrimaryKey;
import org.aplikator.client.shared.data.Record;
import org.aplikator.server.AplikatorServiceServer;
import org.aplikator.server.Context;
import org.aplikator.server.descriptor.Collection;
import org.aplikator.server.descriptor.Entity;
import org.aplikator.server.descriptor.Property;
import org.aplikator.server.descriptor.Reference;

import javax.servlet.http.HttpServletRequest;

import java.text.SimpleDateFormat;
import java.util.*;

public class Utils {
    public static final String NULL_USER_STRING = "----";

    public static Date getDatum(int plusDny, boolean soNe) {
        Calendar cal = new GregorianCalendar();

        cal.add(Calendar.DATE, plusDny);
        if (soNe) {
            while ((cal.get(Calendar.DAY_OF_WEEK) == Calendar.SATURDAY) || (cal.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY)) {
                cal.add(Calendar.DATE, 1);
            }
        }
        return cal.getTime();
    }
    
    public static String removeEnter(String str) {
        String result="";
        result = str.replaceAll("\r", "").replaceAll("\n", "");
        return result;
    }
    
    @SuppressWarnings({ "rawtypes", "unchecked" })
    public static void copyRecord(Record source, Record target, Property... props) {
        for (Property prop : props) {
            prop.setValue(target, prop.getValue(source));
        }
    }

    public static String getWebUser(org.aplikator.server.Context ctx, boolean allowNulls) {
        HttpServletRequest request = ctx.getHttpServletRequest();
        String remoteUser = request.getRemoteUser();
        if (remoteUser == null && (!allowNulls)) {
            remoteUser = NULL_USER_STRING;
        }
        return remoteUser;
    }

    public static java.util.List<ListItem> getStaticList(List<String> sourceList) {
        List<ListItem> listValues = new ArrayList<ListItem>();
        for (String value : sourceList) {
            listValues.add(new ListItem.Default(value, value));
        }
        return listValues;
    }

    public static java.util.List<ListItem> getStaticList(Map<String, String> sourceList) {
        List<ListItem> listValues = new ArrayList<ListItem>();
        for (String value : sourceList.keySet()) {
            listValues.add(new ListItem.Default(value, sourceList.get(value)));
        }
        return listValues;
    }
    
    public static <T extends Entity> Record getReferenceRecord(Record record, Reference<T> reference, Context ctx) {
        if (reference.getValue(record)==null) {
            return null;
        }        
        PrimaryKey pk = new PrimaryKey(reference.referredEntity.getId(), reference.getValue(record));
        Record rec = ctx.getAplikatorService().getRecord(pk.getSerializationString(), reference.referredEntity.view().getId());
        return rec;
    }
    
    public static String getDateAsString(Date datum) {
        SimpleDateFormat sdf = new SimpleDateFormat("dd.MM.yyyy");
        sdf.format(datum);
        return sdf.format(datum);
    }

    public static List<Record> getCollectionRecords(Record ownerRecord, Collection<?> ownerProperty, Context ctx) {
        List<Record> retval = new ArrayList<Record>();
        List<Record> dbRecords = ((AplikatorServiceServer) ctx.getAplikatorService()).getRecords(ownerProperty.referredEntity.view(), null, null, ownerProperty.clientClone(ctx), ownerRecord.getPrimaryKey(), 0, 0, ctx);
        List<ContainerNode> containerRecords = ctx.getRecordContainer().getRecords();
        for (Record dbRec : dbRecords) {
            boolean changed = false;
            for (ContainerNode node : containerRecords) {
                if (Operation.DELETE.equals(node.getOperation())) {
                    if (dbRec.getPrimaryKey().equals(node.getOriginal().getPrimaryKey())) {
                        changed = true;
                        break;
                    }
                }
                if (Operation.UPDATE.equals(node.getOperation())) {
                    if (dbRec.getPrimaryKey().equals(node.getOriginal().getPrimaryKey())) {
                        changed = true;
                        if ((node.getEdited().getProperties().size() == 0)) {
                            retval.add(node.getOriginal());
                        } else {
                            retval.add(node.getEdited());
                        }
                        break;
                    }
                }
            }
            if (!changed) {
                retval.add(dbRec);
            }
        }

        for (ContainerNode node : containerRecords) {
            if (Operation.CREATE.equals(node.getOperation())) {
                if (ownerRecord.getPrimaryKey().equals(node.getEdited().getOwnerPrimaryKey())) {
                    retval.add(node.getEdited());
                }
            }
        }
        return retval;
    }
}